home *** CD-ROM | disk | FTP | other *** search
/ Skunkware 98 / Skunkware 98.iso / osr5 / devtools / dejagnu-971222 / usr / local / share / dejagnu / utils.exp < prev    next >
Encoding:
Text File  |  1998-03-22  |  9.7 KB  |  428 lines

  1. # Copyright (C) 92, 93, 94, 95, 1996, 1997 Free Software Foundation, Inc.
  2.  
  3. # This program is free software; you can redistribute it and/or modify
  4. # it under the terms of the GNU General Public License as published by
  5. # the Free Software Foundation; either version 2 of the License, or
  6. # (at your option) any later version.
  7. # This program is distributed in the hope that it will be useful,
  8. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  9. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10. # GNU General Public License for more details.
  11. # You should have received a copy of the GNU General Public License
  12. # along with this program; if not, write to the Free Software
  13. # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. 
  14.  
  15. # Please email any bugs, comments, and/or additions to this file to:
  16. # bug-dejagnu@prep.ai.mit.edu
  17.  
  18. # This file was written by Rob Savoye. (rob@cygnus.com)
  19.  
  20. #
  21. # Most of the procedures found here mimic their unix counter-part. 
  22. # This file is sourced by runtest.exp, so they are usable by any test case.
  23. #
  24.  
  25. #
  26. # Gets the directories in a directory
  27. #     args: the first is the dir to look in, the next
  28. #         is the pattern to match. It
  29. #         defaults to *. Patterns are csh style
  30. #         globbing rules
  31. #     returns: a list of dirs or NULL
  32. #
  33. proc getdirs { args } {
  34.     set path [lindex $args 0]
  35.     if { [llength $args] > 1} {
  36.     set pattern [lindex $args 1]
  37.     } else {
  38.     set pattern "*"
  39.     }
  40.     verbose "Looking in ${path} for directories that match \"${pattern}\"" 3
  41.     catch "glob ${path}/${pattern}" tmp
  42.     if { ${tmp} != "" } {
  43.     foreach i ${tmp} {
  44.         if [file isdirectory $i] {
  45.         switch -- "[file tail $i]" {
  46.             "testsuite" -
  47.             "config" -
  48.             "lib" -
  49.             "CVS" -
  50.             "RCS" -
  51.             "SCCS" {
  52.             verbose "Ignoring directory [file tail $i]" 3
  53.             continue
  54.             }
  55.             default {
  56.             if [file readable $i] {
  57.                 verbose "Found directory [file tail $i]" 3
  58.                 lappend dirs $i
  59.             }
  60.             }
  61.         }
  62.         }
  63.     }    
  64.     } else {
  65.     perror "$tmp"
  66.     return ""
  67.     }
  68.     
  69.     if ![info exists dirs] {
  70.     return ""
  71.     } else {
  72.     return $dirs
  73.     }
  74. }
  75.  
  76. #
  77. # Finds all the files recursively
  78. #     rootdir - this is the directory to start the search
  79. #         from. This is and all subdirectories are search for
  80. #         filenames. Directory names are not included in the
  81. #         list, but the filenames have path information. 
  82. #     pattern - this is the pattern to match. Patterns are csh style
  83. #         globbing rules.
  84. #     returns: a list or a NULL.
  85. #
  86. proc find { rootdir pattern } {
  87.     # first find all the directories
  88.     set dirs "$rootdir "
  89.     while 1 {
  90.     set tmp $rootdir
  91.     set rootdir ""
  92.     if [string match "" $tmp] {
  93.         break
  94.     }
  95.     foreach i $tmp {
  96.         set j [getdirs $i]
  97.         if ![string match "" $j] {
  98.         append dirs "$j "
  99.         set rootdir $j
  100.         unset j
  101.         } else {
  102.         set rootdir ""
  103.         }
  104.     }
  105.     set tmp ""
  106.     }
  107.     
  108.     # find all the files that match the pattern
  109.     foreach i $dirs {
  110.     verbose "Looking in $i" 3
  111.     set tmp [glob -nocomplain $i/$pattern]
  112.     if { [llength $tmp] != 0 } {
  113.         foreach j $tmp {
  114.         if ![file isdirectory $j] {
  115.             lappend files $j
  116.             verbose "Adding $j to file list" 3
  117.         }
  118.         }
  119.     }
  120.     }
  121.     
  122.     if ![info exists files] {
  123.     lappend files ""
  124.     }
  125.     return $files
  126. }
  127.  
  128. #
  129. # Search the path for a file. This is basically a version
  130. # of the BSD-unix which utility. This procedure depends on
  131. # the shell environment variable $PATH. It returns 0 if $PATH
  132. # does not exist or the binary is not in the path. If the
  133. # binary is in the path, it returns the full path to the binary.
  134. #
  135. proc which { file } {
  136.     global env
  137.     
  138.     # strip off any extraneous arguments (like flags to the compiler)
  139.     set file [lindex $file 0]
  140.     
  141.     # if it exists then the path must be OK
  142.     # ??? What if $file has no path and "." isn't in $PATH?
  143.     if [file exists $file] {
  144.     return $file
  145.     }
  146.     if [info exists env(PATH)] {
  147.     set path [split $env(PATH) ":"]
  148.     } else {
  149.     return 0
  150.     }
  151.     
  152.     foreach i $path {
  153.     verbose "Checking against $i" 3
  154.     if [file exists $i/$file] {
  155.         if [file executable $i/$file] {
  156.         return $i/$file
  157.         } else {
  158.         warning "$i/$file exists but is not an executable"
  159.         }
  160.     }
  161.     }
  162.     # not in path
  163.     return 0
  164. }
  165.  
  166. #
  167. # Looks for a string in a file. 
  168. #     return:list of lines that matched or NULL if none match.
  169. #     args:  first arg is the filename,
  170. #            second is the pattern,
  171. #            third are any options.
  172. #     Options: line  - puts line numbers of match in list
  173. #
  174. proc grep { args } {
  175.     
  176.     set file [lindex $args 0]
  177.     set pattern [lindex $args 1]
  178.     
  179.     verbose "Grepping $file for the pattern \"$pattern\"" 3
  180.     
  181.     set argc [llength $args]
  182.     if { $argc > 2 } {
  183.     for { set i 2 } { $i < $argc } { incr i } {
  184.         append options [lindex $args $i]
  185.         append options " "
  186.     }
  187.     } else {
  188.     set options ""
  189.     }
  190.     
  191.     set i 0
  192.     set fd [open $file r]
  193.     while { [gets $fd cur_line]>=0 } {
  194.     incr i
  195.     if [regexp -- "$pattern" $cur_line match] {
  196.         if ![string match "" $options] {
  197.         foreach opt $options {
  198.             case $opt in {
  199.             "line" {
  200.                 lappend grep_out [concat $i $match]
  201.             }
  202.             }
  203.         }
  204.         } else {
  205.         lappend grep_out $match
  206.         }
  207.     }
  208.     }
  209.     close $fd
  210.     unset fd
  211.     unset i
  212.     if ![info exists grep_out] {
  213.     set grep_out ""
  214.     }
  215.     return $grep_out
  216. }
  217.  
  218. #
  219. # Remove elements based on patterns. elements are delimited by spaces.
  220. # pattern is the pattern to look for using glob style matching
  221. # list is the list to check against
  222. # returns the new list
  223. #
  224. proc prune { list pattern } {
  225.     foreach i $list {
  226.     verbose "Checking pattern \"$pattern\" against $i" 3
  227.     if ![string match $pattern $i] {
  228.         lappend tmp $i
  229.     } else {
  230.         verbose "Removing element $i from list" 3
  231.     }
  232.     }
  233.     return $tmp
  234. }
  235.  
  236. # Attempt to kill a process that you started on the local machine.
  237. #
  238. proc slay { name } {
  239.     set in [open [concat "|ps"] r]
  240.     while {[gets $in line]>-1} {
  241.     if ![string match "*expect*slay*" $line] {
  242.         if [string match "*$name*" $line] {
  243.         set pid [lindex $line 0]
  244.         catch "exec kill -9 $pid]"
  245.         verbose "Killing $name, pid = $pid\n"
  246.         }
  247.     }
  248.     }
  249.     close $in
  250. }
  251.  
  252. #
  253. # Convert a relative path to an absolute one on the local machine.
  254. #
  255. proc absolute { path } {
  256.     if [string match "." $path] {
  257.         return [pwd]
  258.     }
  259.     
  260.     set basedir [pwd]
  261.     cd $path
  262.     set path [pwd]
  263.     cd $basedir
  264.     return $path
  265. }
  266.  
  267. #
  268. # Source a file and trap any real errors. This ignores extraneous
  269. # output. returns a 1 if there was an error, otherwise it returns 0.
  270. #
  271. proc psource { file } {
  272.     global errorInfo
  273.     global errorCode
  274.  
  275.     unset errorInfo
  276.     if [file exists $file] {
  277.     catch "source $file"
  278.     if [info exists errorInfo] {
  279.         send_error "ERROR: errors in $file\n"
  280.         send_error "$errorInfo"
  281.         return 1
  282.     }
  283.     }
  284.     return 0
  285. }
  286.  
  287. #
  288. # Check if a testcase should be run or not
  289. #
  290. # RUNTESTS is a copy of global `runtests'.
  291. #
  292. # This proc hides the details of global `runtests' from the test scripts, and
  293. # implements uniform handling of "script arguments" where those arguments are
  294. # file names (ie: the "foo" in make check RUNTESTFLAGS="bar.exp=foo").
  295. # "glob" style expressions are supported as well as multiple files (with
  296. # spaces between them).
  297. # Eg: RUNTESTFLAGS="bar.exp=foo1.c foo2.c foo3*.c bar*.c"
  298. #
  299. proc runtest_file_p { runtests testcase } {
  300.     if [string length [lindex $runtests 1]] {
  301.     set testcase [file tail $testcase]
  302.     foreach ptn [lindex $runtests 1] {
  303.         if [string match $ptn $testcase] {
  304.         return 1
  305.         }
  306.     }
  307.     return 0
  308.     }
  309.     return 1
  310. }
  311.  
  312. #
  313. # Delete various system verbosities from TEXT on SYSTEM
  314. #
  315. # An example is:
  316. # ld.so: warning: /usr/lib/libc.so.1.8.1 has older revision than expected 9
  317. #
  318. # SYSTEM is typical $target_triplet or $host_triplet.
  319. #
  320.  
  321. #
  322. # Compares two files line-by-line
  323. #     returns 1 it the files match,
  324. #     returns 0 if there was a file error,
  325. #     returns -1 if they didn't match.
  326. #
  327. proc diff { file_1 file_2 } {
  328.     set eof -1
  329.     set differences 0
  330.     
  331.     if [file exists ${file_1}] {
  332.         set file_a [open ${file_1} r]
  333.     } else {
  334.         warning "${file_1} doesn't exist"
  335.         return 0
  336.     }
  337.     
  338.     if [file exists ${file_2}] {
  339.         set file_b [open ${file_2} r]
  340.     } else {
  341.         warning "${file_2} doesn't exist"
  342.         return 0
  343.     }
  344.     
  345.     verbose "# Diff'ing: ${file_1} ${file_2}\n" 1
  346.     
  347.     set list_a ""
  348.     while { [gets ${file_a} line] != ${eof} } {
  349.         if [regexp "^#.*$" ${line}] {
  350.             continue
  351.         } else {
  352.             lappend list_a ${line}
  353.         }
  354.     }
  355.     close ${file_a}
  356.     
  357.     set list_b ""
  358.     while { [gets ${file_b} line] != ${eof} } {
  359.         if [regexp "^#.*$" ${line}] {
  360.             continue
  361.         } else {
  362.             lappend list_b ${line}
  363.         }
  364.     }
  365.     close ${file_b}
  366.     for { set i 0 } { $i < [llength $list_a] } { incr i } {
  367.         set line_a [lindex ${list_a} ${i}]
  368.         set line_b [lindex ${list_b} ${i}]
  369.  
  370. #        verbose "\t${file_1}: ${i}: ${line_a}\n" 3
  371. #        verbose "\t${file_2}: ${i}: ${line_b}\n" 3
  372.         if [string compare ${line_a} ${line_b}] {
  373.         verbose "line #${i}\n" 2
  374.             verbose "\< ${line_a}\n" 2
  375.             verbose "\> ${line_b}\n" 2
  376.  
  377.         send_log "line #${i}\n"
  378.             send_log "\< ${line_a}\n"
  379.             send_log "\> ${line_b}\n"
  380.  
  381.             set differences -1
  382.         }
  383.     }
  384.     
  385.     if { $differences == -1 || [llength ${list_a}] != [llength ${list_b}] } {
  386.     verbose "Files not the same" 2
  387.         set differences -1
  388.     } else {
  389.     verbose "Files are the same" 2
  390.     set differences 1
  391.     }
  392.     return ${differences}
  393. }
  394.  
  395. #
  396. # Set an environment variable
  397. #
  398. proc setenv { var val } {
  399.     global env
  400.     
  401.     set env($var) $val
  402. }
  403.  
  404. #
  405. # Unset an environment variable
  406. #
  407. proc unsetenv { var } {
  408.     global env
  409.     unset env($var)
  410. }
  411.  
  412. #
  413. # Get a value from an environment variable
  414. #
  415. proc getenv { var } {
  416.     global env
  417.  
  418.     if [info exists env($var)] {
  419.     return $env($var)
  420.     } else {
  421.     return ""
  422.     }
  423. }
  424.  
  425.